home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / kabuki.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  8KB  |  192 lines

  1. /***************************************************************************
  2.  
  3. "Kabuki" Z80 encryption
  4.  
  5.  
  6. The "Kabuki" is a custom Z80 module which runs encrypted code. The encryption
  7. key is stored in some battery-backed RAM, therefore the chip has the annoying
  8. habit of stopping working every few years, when the battery dies.
  9. Check at the bottom of this text to see a list of all the known games which
  10. use this chip.
  11.  
  12.  
  13. How it works:
  14. The base operation is a bit swap which affects couples of adjacent bits.
  15. Each of the 4 couples may or may not be swapped, depending on the address of
  16. the byte and on whether it is an opcode or data.
  17. The decryption consists of these steps:
  18. - bitswap
  19. - ROL
  20. - bitswap
  21. - XOR with a key
  22. - ROL
  23. - bitswap
  24. - ROL
  25. - bitswap
  26.  
  27. To know how to apply the byteswap, take the address of the byte to decode and:
  28. - if the byte is an opcode, add addr_key to the address
  29. - if the byte is data, XOR the address with 1FC0, add 1, and then add addr_key
  30. You'll get a 16-bit word. The first two bitswaps depend on bits 0-7 of that
  31. word, while the second two on bits 8-15. When a bit in the word is 1, swap the
  32. two bits, oherwise don't. The exact couple of bits affected depends on the
  33. game and is identified in this file with two keys: swap_key1 and swap_key2
  34. (which are just permutations of the numbers 0-7, not full 32-bit integers).
  35.  
  36.  
  37. Key space size:
  38. - swap_key1  8! = 40320
  39. - swap_key2  8! = 40320
  40. - addr_key   2^16 = 65536
  41. - xor_key    2^8 = 256
  42. - total      2.7274 * 10^16
  43.  
  44.  
  45. Weaknesses:
  46. - 0x00 and 0xff, having all the bits set to the same value, are not affected
  47.   by bit permutations after the XOR. Therefore, their encryption is the same
  48.   regardless of the high 8 bits of the address, and of the value of
  49.   swap_key2. If there is a long stream of 0x00 or 0xff in the original data,
  50.   this can be used to find by brute force all the candidates for swap_key1,
  51.   xor_key, and for the low 8 bits of addr_key. This is a serious weakness
  52.   which dramatically reduces the security of the encryption.
  53. - A 0x00 is always encrypted as a byte with as many 1s as xor_key; a 0xff is
  54.   always encrypted as a byte with as many 0s as xor_key has 1s. So you just
  55.   need to know one 0x00 or 0xff in the unencrypted data to know how many 1s
  56.   there are in xor_key.
  57. - Once you have restricted the range for swap_key1 and you know the number of
  58.   1s in the xor_key, you can easily use known plaintext attacks and brute
  59.   force to find the remaining keys. Long strings like THIS GAME IS FOR USE IN
  60.   and ABCDEFGHIJKLMNOPQRSTUVWXYZ can be found by comparing the number of 1s
  61.   in the clear and encrypted data, taking xor_key into account. When you have
  62.   found where the string is, use brute force to reduce the key space.
  63.  
  64.  
  65. Known games:
  66.                                          swap_key1 swap_key2 addr_key xor_key
  67. Mahjong Gakuen 2 Gakuen-chou no Fukushuu 76543210  01234567    aa55     a5
  68. Poker Ladies                              "    "    "    "      ""      ""
  69. Dokaben                                   "    "    "    "      ""      ""
  70. Dokaben 2                                             unknown
  71. Pang / Buster Bros / Pomping World       01234567  76543210    6548     24
  72. Capcom Baseball                           "    "    "    "      ""      ""
  73. Capcom World                             04152637  40516273    5751     43
  74. Adventure Quiz 2 Hatena ? no Dai-Bouken  45670123  45670123    5751     43
  75. Super Pang                               45670123  45670123    5852     43
  76. Super Buster Bros                        45670123  45670123    2130     12
  77. Super Marukin-Ban                        54321076  54321076    4854     4f
  78. Quiz Tonosama no Yabou                   12345670  12345670    1111     11
  79. Ashita Tenki ni Naare                                 unknown
  80. Quiz Sangokushi                          23456701  23456701    1828     18
  81. Block Block                              02461357  64207531    0002     01
  82.  
  83. Warriors of Fate                         01234567  54163072    5151     51
  84. Cadillacs and Dinosaurs                  76543210  24601357    4343     43
  85. Punisher                                 67452103  75316024    2222     22
  86. Slam Masters                             54321076  65432107    3131     19
  87.  
  88. ***************************************************************************/
  89.  
  90. #include "driver.h"
  91.  
  92.  
  93.  
  94. static int bitswap1(int src,int key,int select)
  95. {
  96.     if (select & (1 << ((key >> 0) & 7)))
  97.         src = (src & 0xfc) | ((src & 0x01) << 1) | ((src & 0x02) >> 1);
  98.     if (select & (1 << ((key >> 4) & 7)))
  99.         src = (src & 0xf3) | ((src & 0x04) << 1) | ((src & 0x08) >> 1);
  100.     if (select & (1 << ((key >> 8) & 7)))
  101.         src = (src & 0xcf) | ((src & 0x10) << 1) | ((src & 0x20) >> 1);
  102.     if (select & (1 << ((key >>12) & 7)))
  103.         src = (src & 0x3f) | ((src & 0x40) << 1) | ((src & 0x80) >> 1);
  104.  
  105.     return src;
  106. }
  107.  
  108. static int bitswap2(int src,int key,int select)
  109. {
  110.     if (select & (1 << ((key >>12) & 7)))
  111.         src = (src & 0xfc) | ((src & 0x01) << 1) | ((src & 0x02) >> 1);
  112.     if (select & (1 << ((key >> 8) & 7)))
  113.         src = (src & 0xf3) | ((src & 0x04) << 1) | ((src & 0x08) >> 1);
  114.     if (select & (1 << ((key >> 4) & 7)))
  115.         src = (src & 0xcf) | ((src & 0x10) << 1) | ((src & 0x20) >> 1);
  116.     if (select & (1 << ((key >> 0) & 7)))
  117.         src = (src & 0x3f) | ((src & 0x40) << 1) | ((src & 0x80) >> 1);
  118.  
  119.     return src;
  120. }
  121.  
  122. static int bytedecode(int src,int swap_key1,int swap_key2,int xor_key,int select)
  123. {
  124.     src = bitswap1(src,swap_key1 & 0xffff,select & 0xff);
  125.     src = ((src & 0x7f) << 1) | ((src & 0x80) >> 7);
  126.     src = bitswap2(src,swap_key1 >> 16,select & 0xff);
  127.     src ^= xor_key;
  128.     src = ((src & 0x7f) << 1) | ((src & 0x80) >> 7);
  129.     src = bitswap2(src,swap_key2 & 0xffff,select >> 8);
  130.     src = ((src & 0x7f) << 1) | ((src & 0x80) >> 7);
  131.     src = bitswap1(src,swap_key2 >> 16,select >> 8);
  132.     return src;
  133. }
  134.  
  135. void kabuki_decode(unsigned char *src,unsigned char *dest_op,unsigned char *dest_data,
  136.         int base_addr,int length,int swap_key1,int swap_key2,int addr_key,int xor_key)
  137. {
  138.     int A;
  139.     int select;
  140.  
  141.     for (A = 0;A < length;A++)
  142.     {
  143.         /* decode opcodes */
  144.         select = (A + base_addr) + addr_key;
  145.         dest_op[A] = bytedecode(src[A],swap_key1,swap_key2,xor_key,select);
  146.  
  147.         /* decode data */
  148.         select = ((A + base_addr) ^ 0x1fc0) + addr_key + 1;
  149.         dest_data[A] = bytedecode(src[A],swap_key1,swap_key2,xor_key,select);
  150.     }
  151. }
  152.  
  153.  
  154.  
  155. static void mitchell_decode(int swap_key1,int swap_key2,int addr_key,int xor_key)
  156. {
  157.     int i;
  158.     unsigned char *rom = memory_region(REGION_CPU1);
  159.     int diff = memory_region_length(REGION_CPU1) / 2;
  160.  
  161.     memory_set_opcode_base(0,rom+diff);
  162.     kabuki_decode(rom,rom+diff,rom,0x0000,0x8000, swap_key1,swap_key2,addr_key,xor_key);
  163.     for (i = 0x10000;i < diff;i += 0x4000)
  164.         kabuki_decode(rom+i,rom+i+diff,rom+i,0x8000,0x4000, swap_key1,swap_key2,addr_key,xor_key);
  165. }
  166.  
  167. void mgakuen2_decode(void) { mitchell_decode(0x76543210,0x01234567,0xaa55,0xa5); }
  168. void pang_decode(void)     { mitchell_decode(0x01234567,0x76543210,0x6548,0x24); }
  169. void cworld_decode(void)   { mitchell_decode(0x04152637,0x40516273,0x5751,0x43); }
  170. void hatena_decode(void)   { mitchell_decode(0x45670123,0x45670123,0x5751,0x43); }
  171. void spang_decode(void)    { mitchell_decode(0x45670123,0x45670123,0x5852,0x43); }
  172. void sbbros_decode(void)   { mitchell_decode(0x45670123,0x45670123,0x2130,0x12); }
  173. void marukin_decode(void)  { mitchell_decode(0x54321076,0x54321076,0x4854,0x4f); }
  174. void qtono1_decode(void)   { mitchell_decode(0x12345670,0x12345670,0x1111,0x11); }
  175. void qsangoku_decode(void) { mitchell_decode(0x23456701,0x23456701,0x1828,0x18); }
  176. void block_decode(void)    { mitchell_decode(0x02461357,0x64207531,0x0002,0x01); }
  177.  
  178.  
  179. static void cps1_decode(int swap_key1,int swap_key2,int addr_key,int xor_key)
  180. {
  181.     unsigned char *rom = memory_region(REGION_CPU2);
  182.     int diff = memory_region_length(REGION_CPU2) / 2;
  183.  
  184.     memory_set_opcode_base(1,rom+diff);
  185.     kabuki_decode(rom,rom+diff,rom,0x0000,0x8000, swap_key1,swap_key2,addr_key,xor_key);
  186. }
  187.  
  188. void wof_decode(void)      { cps1_decode(0x01234567,0x54163072,0x5151,0x51); }
  189. void dino_decode(void)     { cps1_decode(0x76543210,0x24601357,0x4343,0x43); }
  190. void punisher_decode(void) { cps1_decode(0x67452103,0x75316024,0x2222,0x22); }
  191. void slammast_decode(void) { cps1_decode(0x54321076,0x65432107,0x3131,0x19); }
  192.